import numpy as np
from sklearn import preprocessing
from sklearn.naive_bayes import GaussianNB
# 加载数据集
input_file = 'F:/python学习资料/Python-Machine-Learning-Cookbook-master/Chapter02/adult.data.txt'

# 读取数据
X = []
y = []
count_lessthan50k = 0
count_morethan50k = 0
num_images_threshold = 10000

with open(input_file,'r') as f:
    for line in f.readlines():
        if '?' in line:
            continue
        data = line[:-1].split(", ")
        # print(data)
        if data[-1] == '<=50K' and count_lessthan50k < num_images_threshold:
            X.append(data)
            count_lessthan50k = count_lessthan50k + 1
        elif data[-1] == '>=50K' and count_morethan50k < num_images_threshold:
            X.append(data)
            count_morethan50k = count_morethan50k + 1

        if count_lessthan50k >= num_images_threshold and count_morethan50k >= num_images_threshold:
            break

X = np.array(X)
# print(X[:5])
# 我们要把字符型数据转化为数值型数据,并保持数值型数据不变
label_encoder = []
X_encoded = np.empty(X.shape)
for i,item in enumerate(X[0]):
    # isdigit函数用于识别数值型数据
    if item.isdigit():
        X_encoded[:,i] = X[:,i]
    else:
        label_encoder.append(preprocessing.LabelEncoder())
        X_encoded[:,i] = label_encoder[-1].fit_transform(X[:,i])

X = X_encoded[:,:-1].astype(int)
y = X_encoded[:,-1].astype(int)
print(X[:5])

# 然后把数据集划分为训练集和测试集
from sklearn import model_selection
X_train,X_test,y_train,y_test = model_selection.train_test_split(X,y,random_state=5,test_size=0.25)
# 构建分类器
classifier_gaussiannb = GaussianNB()
classifier_gaussiannb.fit(X_train,y_train)
y_test_pred = classifier_gaussiannb.predict(X_test)
# 计算分类器的F1分数
f1 = model_selection.cross_val_score(classifier_gaussiannb,X,y,scoring='f1_weighted',cv=5)
print("F1 score:"+str(round(100*f1.mean(),2))+"%")
# 计算精度
print("accuracy score:"+str(round(100*classifier_gaussiannb.score(X_test,y_test),2))+'%')

# 使用随机森林
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators=50,max_depth=4)
rf.fit(X_train,y_train)
print("随机森林精度:{:.2f}".format(rf.score(X_test,y_test)))
F1 = model_selection.cross_val_score(rf,X_train,y_train,scoring='f1_weighted',cv=5)
print("随机森林F1分数"+str(round(100*F1.mean(),2))+"%")

# 预测数据
input_data = ['39','State-gov','77516','Bachelors','13','Never-married','Adm-clerical',
              'Not-in-family','White','Male','2174','0','40','United-States']
count = 0
input_data_encoded = [-1] * len(input_data)
print(input_data_encoded)
for i,item in enumerate(input_data):
    if item.isdigit():
        input_data_encoded[i] = int(input_data[i])
    else:
        input_data_encoded[i] = int(label_encoder[count].transform([input_data[i]]))
        count = count+1

input_data_encoded = np.array(input_data_encoded)
# 预测并打印特定数据点的输出结果
output_class = classifier_gaussiannb.predict([input_data_encoded])
print(label_encoder[-1].inverse_transform(output_class)[0])